#region File Description
//-----------------------------------------------------------------------------
// Game1.cs
//
// XNAHero.com
// Copyright (C) XNAHero.com. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using RocketRiotDestructibleTexture.Utils;

namespace RocketRiotDestructibleTexture
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Matrix View, Projection;
        Texture2D texture;
        BasicEffect basicEffect;

        private RiotTexture riotTexture;

        private KeyboardState keyBoardState;

        private DestructibleTexture2D destructibleTexture;

        private Vector3 translation;
        float rotation;

        private Texture2D Hud;
        private Vector2 texturePosition = new Vector2(1 , 70);
        private bool showText = true;

        private KeyboardState currentKeyBoardState;
        private KeyboardState previousKeyboardState;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            IsMouseVisible = true;

            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 480;


#if WINDOWS_PHONE
            graphics.IsFullScreen = true;
            graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
#endif
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            texture = Content.Load<Texture2D>("texture1");
            Hud = Content.Load<Texture2D>("hud");
            
            basicEffect = new BasicEffect(GraphicsDevice);
            //basicEffect.EnableDefaultLighting();

            View = Matrix.CreateLookAt(new Vector3 (0, 0, 100), Vector3.Zero, Vector3.Up);

            //Projection = Matrix.CreateOrthographicOffCenter(-256, 256, -256, 256, 1, 1000);
            Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 5.0f / 3.0f, 1, 1000);

            basicEffect.World = Matrix.Identity;
            basicEffect.View = View;
            basicEffect.Projection = Projection;
            basicEffect.TextureEnabled = false;
            basicEffect.VertexColorEnabled = true;

            destructibleTexture = new DestructibleTexture2D(texture, null, GraphicsDevice);

            riotTexture = new RiotTexture(GraphicsDevice, texture, 20f, Vector2.One *3, Vector3.Backward, Vector3.Up);
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            previousKeyboardState = currentKeyBoardState;
            currentKeyBoardState = Keyboard.GetState();

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

#if WINDOWS
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();
#endif

            // TODO: Add your update logic here
            
            //rotation = MathHelper.WrapAngle((float)gameTime.TotalGameTime.TotalMilliseconds / 600);
            //if (rotation < -MathHelper.PiOver2 || rotation > MathHelper.PiOver2)
                //rotation = MathHelper.Pi + rotation;

            if (currentKeyBoardState.IsKeyDown(Keys.Up))
            {
                translation += Vector3.Up;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.Down))
            {
                translation += Vector3.Down;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.Left))
            {
                translation += Vector3.Left;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.Right))
            {
                translation += Vector3.Right;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.Z))
            {
                translation += Vector3.Forward;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.X))
            {
                translation += Vector3.Backward;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.A))
            {
                rotation -= 0.05f;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.S))
            {
                rotation += 0.05f;
            }
            else if (currentKeyBoardState.IsKeyDown(Keys.Space) && previousKeyboardState.IsKeyUp(Keys.Space))
            {
                showText = !showText;
            }

            basicEffect.World = Matrix.CreateRotationY(rotation) * Matrix.CreateTranslation(translation);

            MouseState mouseState = Mouse.GetState();

            if (showText)
            {
                Vector2 mousePosition = new Vector2(mouseState.X, mouseState.Y);

                Vector2 mouseToTexturePosition = mousePosition - texturePosition;

                if (mouseState.LeftButton == ButtonState.Pressed)
                {
                    if (mouseToTexturePosition.X >= 0 && mouseToTexturePosition.Y >= 0 &&
                        mouseToTexturePosition.X < destructibleTexture.Width &&
                        mouseToTexturePosition.Y < destructibleTexture.Height)
                        destructibleTexture.DestroyTexture(new Circle(mouseToTexturePosition, 10));
                    riotTexture.UpdateIndices(destructibleTexture.Texture);
                }
                
            }

            

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {

            GraphicsDevice.Clear(Color.CornflowerBlue);

            if (riotTexture.PrimitiveCount > 0)
            {

                foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    GraphicsDevice.DrawUserIndexedPrimitives
                        <VertexPositionColor>(
                            PrimitiveType.TriangleList,
                            riotTexture.Vertices,
                            0,
                            riotTexture.NumVertices,
                            riotTexture.Indices,
                            0,
                            riotTexture.PrimitiveCount);
                }
            }

            if (showText)
            {
                spriteBatch.Begin();


                spriteBatch.Draw(Hud, Vector2.Zero, Color.White);
                spriteBatch.Draw(destructibleTexture.Texture, texturePosition, Color.White);
                spriteBatch.End();
            }
            base.Draw(gameTime);

            GraphicsDevice.Textures[0] = null;
        }
    }
}
